【Unity功能实现】SmipleLocalization多语言本地化简易版本

您所在的位置:网站首页 unity 语言插件 【Unity功能实现】SmipleLocalization多语言本地化简易版本

【Unity功能实现】SmipleLocalization多语言本地化简易版本

2023-09-03 10:24| 来源: 网络整理| 查看: 265

文章目录

前言

一、基本功能介绍

二、功能详解

1.创建Excel表格,确定所需数据

2.读取Excel表格

3.处理Unity中需要本地化的Text

三、扩展功能

总结

前言

开发超休闲小游戏时,由于大部分游戏都是出海发布的,所以需要支持多语言。

目前运用比较广泛的本地化插件为I2 Localization。不过该插件功能繁杂,于是编写了一个简易版的语言本地化功能。

一、基本功能介绍

项目开发过程中,将数据存放在Excel中方便查看也方便更改。然后通过读取Excel的内容,将其表中内容读取到项目中对应的class实例(LocalizationData)中,然后将该实例生成一个Asset,如图所示:

生成好之后,我们就可以在游戏中通过这个Asset来获取我们需要的数据啦~

二、功能详解 1.创建Excel表格,确定所需数据 首先我们需要知道自己需要哪些数据。这里以我开发的俄罗斯方块案例来说明吧,游戏界面如下:

创建Excel表格,填写数据信息,如图所示:

根据Excel表格,我们需要定义两个枚举。

        第一个枚举:语言类型。

//这里保证与Excel表顺序一致 public enum LanguageType { English = 0,//默认语言类型为英文 Chinese = 1 }

        第二个枚举:需要进行本地化的文本类型Key。

public enum TextKey { Racing_Bricks, Score, High_Score, Speed, Quick, Down, Left, Right, Rotate_Direction } 根据Excel表格,定义三个基础类。

        第一个类:用来存放每行的单元格表数据。

using System; using UnityEngine; namespace SmipleLocalization { [Serializable] public class ItemData { [SerializeField] private string itemName;//语言名称,主要是方便编辑器上查看 public LanguageType languageType;//语言类型 public string content;//对应的内容 //构造函数:初始化数据成员 public ItemData(LanguageType _languageType, string _content) { this.languageType = _languageType; this.itemName = _languageType.ToString(); this.content = _content; } } }

        第二个类:用来存放前者的数组即每行的表数据。

using System; using System.Collections.Generic; using UnityEngine; namespace SmipleLocalization { [Serializable] public class TextLocalization { [SerializeField] private string keyName;//当前文本类型名称,主要是方便编辑器上查看 public TextKey curTextKey;//该文本类型 public List itemDatas = new List();//当前文本类型对应的语言本地化文本信息 //构造函数:初始化 public TextLocalization(string _textKey, params string[] language) { this.keyName = _textKey; this.curTextKey = (TextKey)Enum.Parse(typeof(TextKey), _textKey); for (int i = 0; i < language.Length; i++) { ItemData cnData = new ItemData((LanguageType)i, language[i]); itemDatas.Add(cnData); } } //根据语言类型查找对应语言文本信息 public ItemData GetType(LanguageType t) { for (int i = 0; i < this.itemDatas.Count; i++) { if (this.itemDatas[i].languageType == t) { return this.itemDatas[i]; } } throw new KeyNotFoundException("Language not found: " + t); } } }

        第三个类:用来存放第二个类的数组即所有的表数据。

using UnityEngine; using System; using System.Collections.Generic; namespace SmipleLocalization { public class LocalizationData : ScriptableObject { public List localizationTxts = new List(); /// /// 根据TextKey获取对应的所有语言类型信息 /// /// 需要本地化的文本 public TextLocalization GetTextInfo(TextKey k) { for (int i = 0; i < this.localizationTxts.Count; i++) { if (this.localizationTxts[i].curTextKey == k) { return this.localizationTxts[i]; } } //return null; throw new KeyNotFoundException("TextKey not found: " + k); } } } 2.读取Excel表格 需要引入Excel.dll和ICSharpCode.SharpZipLib库文件,放到Plugins文件夹下。

        下载地址:Unity读取和写入Excel表格所需dll-Unity3D文档类资源-CSDN文库

在Editor文件夹下创建cs文件去实现读取Excel操作。       

        1.定义一个类,里面存放我们需要的字段:

using UnityEngine; namespace SmipleLocalization { public class LocalizationExcelConfig : MonoBehaviour { /// /// 存放将Excel表格数据转化CS文件的文件夹路径 /// public static readonly string assetFolderPath = "Assets/Resources/Datas/"; /// /// 存放将Excel表格数据转化CS文件的路径 /// public static readonly string assetPath = string.Format("{0}{1}.asset", assetFolderPath, "LanguageLocalizationData"); /// /// 加载文件的路径 /// public static readonly string loadAssetPath = "Datas/LanguageLocalizationData"; } }

        2.定义一个类,用来读取Excel表格的数据,并解析数据存放到Asset中

using System.Collections.Generic; using System.Data; using System.IO; using Excel; namespace SmipleLocalization { public class LocalizationExcelTool { /// /// 读取表格数据,生成对应的数据 /// public static List CreateDataWithExcel(string filePath) { List localizationTxts = new List(); //获得表格数据 int row = 0, column = 0; DataRowCollection collection = ReadExcel(filePath, ref row, ref column); //根据Excel表的定义,第二行开始才是数据 for (int i = 1; i < row; i++) { string[] language = new string[column - 1]; for (int j = 1; j < column; j++) { language[j - 1] = collection[i][j].ToString(); } TextLocalization tl = new TextLocalization(collection[i][0].ToString(), language); localizationTxts.Add(tl); } return localizationTxts; } /// /// 读取Excel文件内容 /// /// 文件路径 /// 行数 /// 列数 private static DataRowCollection ReadExcel(string filePath, ref int row, ref int column) { FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); IExcelDataReader edReader = ExcelReaderFactory.CreateOpenXmlReader(stream); DataSet result = edReader.AsDataSet(); //Tables[0]下标0表示Excel文件中第一张表的数据 row = result.Tables[0].Rows.Count; column = result.Tables[0].Columns.Count; return result.Tables[0].Rows; } } }

        3.将拿到的数据存放在LocalizationData中,并生成一个Asset文件:

using System.IO; using UnityEditor; using UnityEngine; namespace SmipleLocalization { public class BuildExcelDataEditor : Editor { [MenuItem("CustomEditor/CreateLocalizationData")] public static void CreateLocalizationData() { //打开Excel string filePath = EditorUtility.OpenFilePanel("Open Localization Excel", "", "xlsx"); //获取Excel数据 LocalizationData data = ScriptableObject.CreateInstance(); data.localizationTxts = LocalizationExcelTool.CreateDataWithExcel(filePath); //判断文件夹是否存在 if (!Directory.Exists(LocalizationExcelConfig.assetFolderPath)) { Directory.CreateDirectory(LocalizationExcelConfig.assetFolderPath); } string assetPath = LocalizationExcelConfig.assetPath; //判断文件是否已经存在 //若已经存在,则删除该文件 if (File.Exists(assetPath)) { AssetDatabase.DeleteAsset(assetPath); } //生成一个Asset文件 AssetDatabase.CreateAsset(data, assetPath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } }

        这样我们就可以在Unity中选择我们自定义的菜单CustromEditor->CreateLocalizationData,然后选择我们需要的Excel表格,即可生成Asset了。

3.处理Unity中需要本地化的Text 创建一个类,在游戏运行时,加载数据,为目标提供本地化方法 using UnityEngine; using System; namespace SmipleLocalization { public static class LocalizationSys { private static LocalizationData localizationDatas; public static Action ChangeCurLanguageTypeEvent;//监听语言类型变化事件,在事件触发时设置内容,主要是方便用来游戏运行中测试本地化 private static LanguageType mCurLanguageType; static LocalizationSys() { InitDatas(); InitLanguageType(); } /// /// 加载数据 /// private static void InitDatas() { localizationDatas = Resources.Load(LocalizationExcelConfig.loadAssetPath); } /// /// 根据系统语言设置默认语言 /// private static void InitLanguageType() { SystemLanguage languageStr = Application.systemLanguage; if (languageStr == SystemLanguage.Chinese || languageStr == SystemLanguage.ChineseSimplified) { CurLanguageType = LanguageType.Chinese; } else { CurLanguageType = LanguageType.English; } } /// /// 设置当前语言类型 /// public static LanguageType CurLanguageType { set { if (mCurLanguageType != value) { mCurLanguageType = value; ChangeCurLanguageTypeEvent?.Invoke(); } } } /// /// 对应的语言本地化 /// /// 需要本地化的文本 public static string Localize(TextKey textKey) { return Localize(textKey, mCurLanguageType); } /// /// 获取对应的语言本地化 /// /// 需要本地化的文本 /// 语言类型 /// private static string Localize(TextKey textKey, LanguageType languageType) { string value = string.Empty; TextLocalization textInfo = localizationDatas.GetTextInfo(textKey); if (textInfo != null) { ItemData typeInfo = textInfo.GetType(languageType); //如果没找到对应语言本地化信息,则设置默认英文信息 if (typeInfo == null) { typeInfo = textInfo.GetType(LanguageType.English); } value = typeInfo.content; } return value; } } //这里保证与Excel表顺序一致 public enum LanguageType { English = 0,//默认语言类型为英文 Chinese = 1 } public enum TextKey { Racing_Bricks, Score, High_Score, Speed, Quick, Down, Left, Right, Rotate_Direction } } 创建一个类,用来设置文本文字内容 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace SmipleLocalization { public class UITextLocalize : MonoBehaviour { private Text mText; [SerializeField] private TextKey textKey; private void Awake() { this.mText = base.GetComponent(); } private void Start() { LocalizationSys.ChangeCurLanguageTypeEvent += OnChangeLanguage; this.OnChangeLanguage(); } private void OnDestroy() { LocalizationSys.ChangeCurLanguageTypeEvent -= OnChangeLanguage; } private void OnChangeLanguage() { this.StaticSet(); } private void StaticSet() { this.mText.text = LocalizationSys.Localize(textKey); } } } 在需要本地化的文本上挂上UITextLocalize脚本,并配置对应的信息,如下所示:

如果我们需要在游戏中测试多语言功能,可以在画布下创建一个DropDown,设置Options,添加OnValueChanged事件,如下所示: public void OnChangeLanguage(int value) { LocalizationSys.CurLanguageType = (LanguageType)value; }

这样我们就可以在游戏运行中查看我们的多语言本地化是否正确了。

三、扩展功能

这款游戏中我只用到了静态文本,但是有时候我们还需要简单的动态修改文本内容。这个时候我们修改一下UITextLocalize脚本即可,如下:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace SmipleLocalization { public class UITextLocalize : MonoBehaviour { private Text mText; [SerializeField] private TextKey textKey; [SerializeField] private LocalizeType localizeType = LocalizeType.Static; private object[] args; private void Awake() { this.mText = base.GetComponent(); } private void Start() { LocalizationSys.ChangeCurLanguageTypeEvent += OnChangeLanguage; this.OnChangeLanguage(); } private void OnDestroy() { LocalizationSys.ChangeCurLanguageTypeEvent -= OnChangeLanguage; } private void OnChangeLanguage() { if (this.localizeType == LocalizeType.Static) { this.StaticSet(); } else if(this.args != null) { this.DynamicSet(this.args); } } private void StaticSet() { this.mText.text = LocalizationSys.Localize(textKey); } /// /// 动态设置文本内容 /// public void DynamicSet(params object[] _args) { string format = LocalizationSys.Localize(textKey); this.mText.text = string.Format(format, _args); this.args = _args; } } }

然后在Inspector面板上设置UITextLocalize的LocalizeType为Dynamic。

接着在需要动态修改Text内容时,不是调用GetComponent().text去设置,而是调用GetComponent().DynamicSet(),传入需要修改的数据即可。参考如下:

总结

大家也可以试试导入EPPlus.dll,用来向Excel写入数据。后续会给大家整理一下。今天就到这里啦~

以上就是今天要讲的内容,如果有哪里不懂的可以留言交流一下。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3